#!/usr/bin/env python
# -*- coding: utf-8 -*-

# 安装模块:  pip3 install paramiko


import re
import os
import sys
import time
import socket
import subprocess
import argparse
import logging
from logging.handlers import RotatingFileHandler
import shlex

try:
    import paramiko
except:
    shlex.os.system("pip install  paramiko")
    import paramiko


results = {
    'unsuccessful': [],
    'successful': [],
}


def parse_args():

    content = """ssh远程工具 ^_^

        ./ssh_paramiko.py  -h 192.168.0.111   -p123456  --run "who -b"
        """
    parser = argparse.ArgumentParser(
        usage="paramiko ssh",
        description=content,
        add_help=False,
        formatter_class=lambda prog: argparse.RawTextHelpFormatter(
            prog, max_help_position=50)
    )
    parser.add_argument("--help",
                        action="help",
                        help="查看帮助信息")
    parser.add_argument('-u', '--user',
                        default="root",
                        help='系统用户名,默认root')

    parser.add_argument('-h', '--host',
                        help='服务器IP')

    parser.add_argument('-p', '--passwd',
                        help='服务器密码')

    parser.add_argument('-P', '--port',
                        type=int,
                        default=22,
                        help='服务器端口,默认为22')

    parser.add_argument('-r', '--run',
                        default="uptime",
                        help='执行命令,默认 uptime')

    args = parser.parse_args()
    return args


class LoggerLog(object):
    def __init__(self, name=__name__):
        """
        实例化LoggerFactory类时的构造函数
        :param name:
        """
        # 实例化logging
        self.logger = logging.getLogger(name)
        # 输出的日志格式
        self.formatter = formatter = logging.Formatter(
            '%(asctime)s %(name)s %(levelname)s %(message)s')

    def create_logger(self):
        """
        构造一个日志对象
        :return:
        """

        # 设置日志输出的文件
        os.makedirs('logs', exist_ok=True)
        # handle = logging.FileHandler('./logs/scripts.log')
        handle = logging.handlers.RotatingFileHandler(
            './logs/scripts.log', maxBytes=1024*1024, backupCount=3)

        # 输出到日志文件的日志级别
        handle.setLevel(logging.INFO)
        handle.setFormatter(self.formatter)
        self.logger.addHandler(handle)
        # 输出到控制台的显示信息
        console = logging.StreamHandler()
        console.setLevel(logging.DEBUG)
        console.setFormatter(self.formatter)
        self.logger.addHandler(console)


def ssh_remote_exec(args):
    date = time.strftime("%b %d %H:%M:%S", time.localtime())
    print(
        "INFO:\t%s\t[\033[1;32m%s\033[0m] Trying to connect　..." % (date, args.host))
    paramiko.util.log_to_file('paramiko.log')

    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    count = 0
    try:
        if args.passwd:
            ssh.connect(
                hostname=args.host,
                username=args.user,
                password=args.passwd,
                port=args.port,
                timeout=3, allow_agent=False)
        else:

            private_key = paramiko.RSAKey.from_private_key_file(
                "/Users/lijingjing/.ssh/TZadmin.pem")
            ssh.connect(
                hostname=args.host,
                username=args.user,
                pkey=private_key,
                port=args.port,
                timeout=3, allow_agent=False, look_for_keys=False)

        stdin, stdout, stderr = ssh.exec_command(
            "source /etc/profile ; %s" % args.run)
        result = stdout.read().decode() + stderr.read().decode()
        results['successful'].append(args.host)
        return result

    except (paramiko.ssh_exception.AuthenticationException,) as e:
        print("INFO:\t%s\t\033[1;31mLogin failed\033[0m\t%s" % (date, e))
        results['unsuccessful'].append(args.host)
    except (paramiko.ssh_exception.NoValidConnectionsError, socket.gaierror, socket.timeout, socket.error) as e:
        print("INFO:\t%s\t\033[1;31mConnection failed\033[0m\t%s" % (date, e))
        results['unsuccessful'].append(args.host)
    except Exception as e:
        print(e, type(e))
    finally:
        ssh.close()


if __name__ == '__main__':
    if len(sys.argv) == 1:
        """ 如果没有参数则查看帮助信息 """
        sys.argv.append("--help")
        args = parse_args()
        sys.exit(1)

    args = parse_args()

    ret = ssh_remote_exec(args)
    print(ret)

    # print("执行成功主机数: count", len(results['successful']), results['successful'])
    # print("执行失败主机数: count", len(
    #     results['unsuccessful']), results['unsuccessful'])
